package com.yuandian.management.utils;

import com.googlecode.ipv6.IPv6Address;

import java.math.BigInteger;

public final class IpUtil {

    public static final BigInteger IPV4_MAX_VALUE = BigInteger.valueOf(4294967295L);    // 255.255.255.255

    /**
     * 将 String 格式的 ipv4 地址转换为 long 格式
     */
    private static long ipv4String2Long(String ip) {
        String[] parts = ip.split("\\.");
        long a = Long.parseLong(parts[0]);
        long b = Long.parseLong(parts[1]);
        long c = Long.parseLong(parts[2]);
        long d = Long.parseLong(parts[3]);
        return (a << 24) + (b << 16) + (c << 8) + (d);
    }

    /**
     * 将 long 格式的 ipv4 地址转换为 String 格式
     */
    private static String ipv4Long2String(long ip) {
        return "" + (ip >>> 24) + "." + ((ip & 0x00FFFFFF) >>> 16) + "." + ((ip & 0x0000FFFF) >>> 8) + "." + (ip & 0x000000FF);
    }

    /**
     * 将长整型的mac地址转成字符串
     *
     * @param mac mac地址
     * @return 字符串型的mac地址
     */
    public static String macLongToStr(Long mac) {
        return mac == null
                ? null
                : String.format("%1$02x-%2$02x-%3$02x-%4$02x-%5$02x-%6$02x",
                (mac) & 0xff, (mac >> 8) & 0xff,
                (mac >> 16) & 0xff, (mac >> 24) & 0xff,
                (mac >> 32) & 0xff, (mac >> 40) & 0xff);
    }

    /**
     * 将ipv4/ipv6 ip地址转换为十进制数字格式
     *
     * @param ip iPv4 字符串形式: 192.168.0.1
     *           iPv6 字符串形式:
     *           1) 冒分十六进制表示法，ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
     *           2) 0位压缩表示法，	fe80::226:2dff:fefa:cd1f
     *           3) 内嵌IPv4地址表示法，::192.168.0.1、::FFFF:192.168.0.1
     * @return 十进制格式ip, '-'开头代表ipv6地址，否则代表ipv4地址
     */
    public static String customIpStr2number(String ip){
        ip = ip.replace(" ", "");
        if (ip.contains(":")) {
            return "-".concat(IPv6Address.fromString(ip).toBigInteger().toString());
        } else {
            return "" + ipv4String2Long(ip);
        }
    }

    /**
     * 将十进制格式ip转换为 点分⼗进制/冒分⼗六进制格式
     * @param ipNumber 十进制格式ip, '-'开头代表ipv6地址，否则代表ipv4地址
     * @return
     */
    public static String customIpNumber2Str(String ipNumber){
        if (ipNumber.substring(0, 1).equals("-")) {
            return IPv6Address.fromBigInteger(new BigInteger(ipNumber.substring(1))).toString();
        } else {
            return ipv4Long2String(Long.parseLong(ipNumber));
        }
    }

    /**
     * 比较ipv4/ipv6 十进制格式ip大小
     * @param ipNumber1 十进制格式ip, '-'开头代表ipv6地址，否则代表ipv4地址
     * @param ipNumber2 十进制格式ip, '-'开头代表ipv6地址，否则代表ipv4地址
     * @return
     */
    public static int customCompareIpNumber(String ipNumber1, String ipNumber2){
        return new BigInteger(ipNumber1).abs().compareTo(new BigInteger(ipNumber2).abs());
    }

}
